package com.itlong.cloud.intercept;

import com.itlong.cloud.POJO.PO.OperateUserInfoPO;
import com.itlong.cloud.POJO.PO.OperationLogPO;
import com.itlong.cloud.POJO.PO.UserLoginLogPO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.enumerate.SystemTypeEnum;
import com.itlong.cloud.noncore.commons.IOperationLogServiceClient;
import com.itlong.cloud.noncore.commons.IUserLoginLogServiceClient;
import com.itlong.cloud.user.operate.IOperateUserInfoServiceClient;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * <desc>
 *      用户操作日志拦截器。
 * </desc>
 *
 * @createDate 2017/08/29
 */
@Aspect
@Component
public class OperationLogIntercept {

 // 定义一个切入点
    @Pointcut("execution(* com.itlong.cloud.controller..*.*(..))")
    public void excudeService(){}

    @Autowired
    IOperationLogServiceClient iOperationLogServiceClient;

    @Autowired
    IOperateUserInfoServiceClient iOperateUserInfoServiceClient;

    @Autowired
    IUserLoginLogServiceClient iUserLoginLogServiceClient;
    /**
     * <desc>
     *      用户操作日志证拦截器
     *      注：每个系统的操作日志拦截器需在拦截器中指定SystemType 对应枚举类 SystemTypeEnum
     * </desc>
     *
     * @return
     * @author Jiaqi.X
     * @createDate 2017/10/16
     */
    @Around("excudeService() && @annotation(loggerInfo)")
    public Object twiceAsOld(ProceedingJoinPoint thisJoinPoint,LoggerInfo loggerInfo) throws Throwable {
        Object result = thisJoinPoint.proceed();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = HttpProtocolUtil.getIpAddr(request);
        //使用正则表达式校验IP的格式是否正确
        String pattern="^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";
        boolean isMatch= Pattern.matches(pattern, ip);
        ip = isMatch?ip:"";
        if ("login".equals(loggerInfo.identifer())){
            UserLoginLogPO userLog = (UserLoginLogPO) request.getAttribute("userLog");
            if (userLog != null) {
//                System.err.print(userLog);
                iUserLoginLogServiceClient.save(userLog);
            }
        }else {
            MessageVO messageVO = (MessageVO)result;
            Map<String,Object> map = StringUtils.isNotBlank(messageVO.getExtend()) ? JsonUtil.toObject(messageVO.getExtend(), HashMap.class) : null;
            String dataId = map != null ? StringHandlerUtil.getNullOrStringForObject(map.get("dataId")) : null;
            String uri = request.getRequestURI();
            OperationLogPO log=new OperationLogPO();
            String token=request.getParameter("token");
            if (token == null) {
                token = request.getAttribute("token") == null ? "" : request.getAttribute("token").toString();
            }
            //获取登录用户信息
            OperateUserInfoPO userInfo=iOperateUserInfoServiceClient.retrieve(token);
            if (userInfo != null && StringUtils.isNotBlank(userInfo.getUserName())) {
                log.setAccount(userInfo.getUserName());
                log.setRealName(userInfo.getRealName());
                log.setIp(ip);
                log.setSystemType(SystemTypeEnum.OPERATE.getType());
                log.setOperationUse(loggerInfo.operateDesc());
                log.setUrl(uri);
                log.setDataId(dataId);
                //保存操作记录
                iOperationLogServiceClient.save(log);
            }
        }
        return result;
    }

}
